package net.xxcxcxcx.xc_enhancedmob.config.skill;

import com.google.gson.annotations.Expose;
import net.xxcxcxcx.xc_enhancedmob.config.BaseConfig;
import net.xxcxcxcx.xc_enhancedmob.skills.Skill;
import net.xxcxcxcx.xc_enhancedmob.skills.SkillHelper;
import net.xxcxcxcx.xc_enhancedmob.skills.SkillRarity;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import static net.xxcxcxcx.xc_enhancedmob.skills.SkillHelper.AllSkills;

public class SkillsConfig extends BaseConfig {
    @Expose(deserialize = false)
    public String message = getMessage();
    @Expose
    public List<SkillConfig> SkillConfigs = BuildSkillConfig();
    public Map<String, SkillConfig> SkillConfigsList = SkillConfigs.stream().collect(Collectors.toMap(SkillConfig::getKey, f -> f));
    public Map<String, SkillConfig> DefaultSkillConfigsList = SkillConfigs.stream().collect(Collectors.toMap(SkillConfig::getKey, f -> f));

    public SkillsConfig() {
        setName("SkillsConfig");
        setFilename("Skill/");
    }

    public String getMessage() {
        String s = "所有技能的配置文件，自动生成，不会自动处理失效文件，但是会自动修正生效但错误的文件，或者生成对应的默认文件。";
        return s;
    }

    public List<SkillConfig> BuildSkillConfig() {
        List<SkillConfig> configList = new ArrayList<>();
        configList.add(new SkillConfig("Default", 100, 100,
                100, 100,
                100, 100,
                new ArrayList<>(), new ArrayList<>(),
                "这是一个默认的技能描述文本，如果你在游戏内看到了这段话，很有可能代表你的游戏产生了错误，请帮忙汇报给作者，QQ:1160510507",
                SkillRarity.Unknown));
        for (SkillHelper.SkillMaker skill : AllSkills) {
            try {
                Constructor constructor = skill.getaClass().getConstructor();
                configList.add(((Skill) constructor.newInstance()).getDefaultConfig());
            } catch (NoSuchMethodException | IllegalAccessException | InstantiationException |
                     InvocationTargetException e) {
                throw new RuntimeException(e);
            }
        }
        configList.sort((a, b) -> {
            if (a.getRarity().count == b.getRarity().count) {
                return a.getKey().compareTo(b.getKey());
            } else return a.getRarity().count - b.getRarity().count;
        });
        return configList;
    }

    @Override
    public void RepairData() {
        super.RepairData();
        for (int i = 0; i < SkillConfigs.size(); i++) {
            SkillConfig skillConfig = SkillConfigs.get(i);
            if (skillConfig.getKey().equals("Default")) {
                SkillConfigs.set(i, DefaultSkillConfigsList.get("Default"));
            }
        }
        for (SkillConfig skillConfig : SkillConfigs) {
            if (skillConfig.getConflict() == null) {
                if (DefaultSkillConfigsList.get(skillConfig.getKey()) != null) {
                    skillConfig.setConflict(DefaultSkillConfigsList.get(skillConfig.getKey()).getConflict());
                } else {
                    skillConfig.setConflict(DefaultSkillConfigsList.get("Default").getConflict());
                }
            }
            if (skillConfig.getLevelCost() == null) {
                if (DefaultSkillConfigsList.get(skillConfig.getKey()) != null) {
                    skillConfig.setLevelCost(DefaultSkillConfigsList.get(skillConfig.getKey()).getLevelCost());
                } else {
                    skillConfig.setLevelCost(DefaultSkillConfigsList.get("Default").getLevelCost());
                }
            }
            if (skillConfig.getMaxlevel() == null) {
                if (DefaultSkillConfigsList.get(skillConfig.getKey()) != null) {
                    skillConfig.setMaxlevel(DefaultSkillConfigsList.get(skillConfig.getKey()).getMaxlevel());
                } else {
                    skillConfig.setMaxlevel(DefaultSkillConfigsList.get("Default").getMaxlevel());
                }
            }
            if (skillConfig.getPreparationtime() == null) {
                if (DefaultSkillConfigsList.get(skillConfig.getKey()) != null) {
                    skillConfig.setPreparationtime(DefaultSkillConfigsList.get(skillConfig.getKey()).getPreparationtime());
                } else {
                    skillConfig.setPreparationtime(DefaultSkillConfigsList.get("Default").getPreparationtime());
                }
            }
            if (skillConfig.getCooldown() == null) {
                if (DefaultSkillConfigsList.get(skillConfig.getKey()) != null) {
                    skillConfig.setCooldown(DefaultSkillConfigsList.get(skillConfig.getKey()).getCooldown());
                } else {
                    skillConfig.setCooldown(DefaultSkillConfigsList.get("Default").getCooldown());
                }
            }
            if (skillConfig.getInsideCooldown() == null) {
                if (DefaultSkillConfigsList.get(skillConfig.getKey()) != null) {
                    skillConfig.setInsideCooldown(DefaultSkillConfigsList.get(skillConfig.getKey()).getInsideCooldown());
                } else {
                    skillConfig.setInsideCooldown(DefaultSkillConfigsList.get("Default").getInsideCooldown());
                }
            }
            if (skillConfig.getMaxUseCount() == null) {
                if (DefaultSkillConfigsList.get(skillConfig.getKey()) != null) {
                    skillConfig.setMaxUseCount(DefaultSkillConfigsList.get(skillConfig.getKey()).getMaxUseCount());
                } else {
                    skillConfig.setMaxUseCount(DefaultSkillConfigsList.get("Default").getMaxUseCount());
                }
            }
            if (skillConfig.getInsideMaxUseCount() == null) {
                if (DefaultSkillConfigsList.get(skillConfig.getKey()) != null) {
                    skillConfig.setInsideMaxUseCount(DefaultSkillConfigsList.get(skillConfig.getKey()).getInsideMaxUseCount());
                } else {
                    skillConfig.setInsideMaxUseCount(DefaultSkillConfigsList.get("Default").getInsideMaxUseCount());
                }
            }
            if (DefaultSkillConfigsList.get(skillConfig.getKey()) != null) {
                skillConfig.setName(DefaultSkillConfigsList.get(skillConfig.getKey()).getName());
                skillConfig.setRarity(DefaultSkillConfigsList.get(skillConfig.getKey()).getRarity());
                Class skill = SkillHelper.getSkillClass(skillConfig.getKey());
                if (skill != null) {
                    try {
                        Constructor constructor = skill.getConstructor();
                        skillConfig.setMessage(((Skill) constructor.newInstance()).getConfigMessage(skillConfig));
                    } catch (NoSuchMethodException | IllegalAccessException | InstantiationException |
                             InvocationTargetException e) {
                        throw new RuntimeException(e);
                    }
                }
            } else {
                skillConfig.setRarity(DefaultSkillConfigsList.get("Default").getRarity());
            }
        }
        SkillConfigsList = SkillConfigs.stream().collect(Collectors.toMap(SkillConfig::getKey, f -> f));
        Set<String> strings = DefaultSkillConfigsList.keySet();
        strings.forEach(s -> {
            if (SkillConfigsList.get(s) == null) {
                SkillConfigsList.put(s, DefaultSkillConfigsList.get(s));
                SkillConfigs.add(DefaultSkillConfigsList.get(s));
            }
        });
        SkillConfigs.sort((a, b) -> {
            if (a.getRarity().count == b.getRarity().count) {
                return a.getKey().compareTo(b.getKey());
            } else return a.getRarity().count - b.getRarity().count;
        });
    }

    public SkillConfig getConfig(String s) {
        if (SkillConfigsList.containsKey(s)) {
            return SkillConfigsList.get(s);
        }
        return SkillConfigsList.get("Default");
    }

}
